package cn.iocoder.yudao.module.infrastructure.user.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.iocoder.yudao.framework.common.biz.permission.enums.RoleCodeEnum;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.infrastructure.user.AdminUserApiV2;
import cn.iocoder.yudao.module.api.infrastructure.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.api.infrastructure.user.dto.SystemUserCreateReqDTO;
import cn.iocoder.yudao.module.infrastructure.permission.dal.dataobject.RoleDO;
import cn.iocoder.yudao.module.infrastructure.permission.dal.dataobject.UserRoleDO;
import cn.iocoder.yudao.module.infrastructure.permission.dal.mysql.RoleMapper;
import cn.iocoder.yudao.module.infrastructure.permission.dal.mysql.UserRoleMapper;
import cn.iocoder.yudao.module.infrastructure.permission.service.PermissionService;
import cn.iocoder.yudao.module.infrastructure.user.dal.dataobject.AdminUserDO;
import cn.iocoder.yudao.module.infrastructure.user.service.AdminUserService;
import cn.iocoder.yudao.module.infrastructure.user.vo.AdminUserSaveReqVO;
import com.github.yulichang.toolkit.JoinWrappers;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Validated
public class AdminUserApiV2Impl implements AdminUserApiV2 {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private AdminUserService adminUserService;
    @Resource
    private PermissionService permissionService;

    @Override
    public Long createUser(SystemUserCreateReqDTO dto) {
        // 创建后台管理员账号
        AdminUserSaveReqVO reqVO = BeanUtils.toBean(dto, AdminUserSaveReqVO.class);
        reqVO.setNickname(dto.getName());
        if (PhoneUtil.isMobile(dto.getUsername())) {
            // 若用户名是手机号码，未被占用则设置手机号码（创建用户时校验了手机号码的唯一性）
            AdminUserDO adminUserDO = adminUserService.getUserByMobile(dto.getUsername());
            if (adminUserDO == null) {
                reqVO.setMobile(dto.getUsername());
            }
        }
        Long userId = adminUserService.createUser(reqVO);
        // 分配角色
        RoleDO roleDO = roleMapper.selectByCode(dto.getRoleCode());
        if (roleDO != null) {
            permissionService.assignUserRole(userId, CollUtil.newHashSet(roleDO.getId()));
        }
        return userId;
    }

    @Nullable
    @Override
    public AdminUserRespDTO getByUsername(String username) {
        AdminUserDO adminUserDO = adminUserService.getUserByUsername(username);
        return BeanUtils.toBean(adminUserDO, AdminUserRespDTO.class);
    }

    @Nullable
    @Override
    public AdminUserRespDTO getUserByMobile(String mobile) {
        AdminUserDO adminUserDO = adminUserService.getUserByMobile(mobile);
        return BeanUtils.toBean(adminUserDO, AdminUserRespDTO.class);
    }

    @Override
    public Set<String> getRoleCodes(Long userId) {
        List<RoleDO> list = roleMapper.selectJoinList(RoleDO.class, JoinWrappers.lambda(RoleDO.class)
                .select(RoleDO::getCode)
                .leftJoin(UserRoleDO.class, UserRoleDO::getRoleId, RoleDO::getId)
                .eq(UserRoleDO::getUserId, userId));
        if (CollUtil.isEmpty(list)) {
            return new HashSet<>();
        }
        return list.stream().map(RoleDO::getCode).collect(Collectors.toSet());
    }

    @Override
    public void updateUserStatus(Long id, Integer status) {
        adminUserService.updateUserStatus(id, status);
    }

    @Override
    public String getUsernameById(Long id) {
        AdminUserDO adminUserDO = adminUserService.getUser(id);
        if (adminUserDO == null) {
            return "";
        }
        if (CommonStatusEnum.isDisable(adminUserDO.getStatus())) {
            return "";
        }
        return adminUserDO.getUsername();
    }

    @Nonnull
    @Override
    public List<Long> getUserIdsByRoleCode(RoleCodeEnum roleCode) {
        RoleDO roleDO = roleMapper.selectByCode(roleCode.getCode());
        if (roleDO == null) {
            return new ArrayList<>();
        }
        List<UserRoleDO> list = userRoleMapper.selectList(UserRoleDO::getRoleId, roleDO.getId());
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(UserRoleDO::getUserId).collect(Collectors.toList());
    }

    @Override
    public void deleteById(Long id) {
        adminUserService.deleteUser(id);
    }

}
